using System;
using System.Collections.Generic;
using System.Linq;
using Castle.DynamicProxy;
using HardMock.Domain;

namespace HardMock.Recording
{
    internal class FilteredMethodCallFactory : IMethodCallFactory
    {
        private readonly IMethodCallFactory methodCallFactory;
        private readonly IEnumerable<Type> excludedTypes;

        public FilteredMethodCallFactory(IMethodCallFactory methodCallFactory, IEnumerable<Type> excludedTypes)
        {
            this.methodCallFactory = methodCallFactory;
            this.excludedTypes = excludedTypes;
        }

        private MethodCall Filter(MethodCall methodCall)
        {
            return new MethodCall(
                methodCall.Assembly,
                methodCall.Type,
                methodCall.Name,
                methodCall.Arguments.Select(a => Filter(excludedTypes, a)));
        }

        private static Argument Filter(IEnumerable<Type> excludedTypes, Argument argument)
        {
            return excludedTypes.Contains(argument.Type) ? new Argument(argument.Type, new IgnoredType()) : argument;
        }

        public MethodCall Create(IInvocation invocation)
        {
            return Filter(methodCallFactory.Create(invocation));
        }
    }
}